﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using INNOVACALL.Framework.Common.MVCHelpers;
using INNOVACALL.Framework.Common.Extensions;
using System.Net;

namespace INNOVACALL.Framework.Common.Controllers
{
    /// <summary>
    /// All controllers must innherit this base class
    /// </summary>
    [CacheManager(enCacheMode.NoCache)]
    public abstract class _Controllers_Base<T> : Controller where T : INNOVACALL.Framework.Common.Models._Models_Base
    {

        //Those lines 
        protected string eMethodBase = "INNOVACALL.Framework.Common.Controllers._Controllers_Base<T>";
        /// <summary>
        /// Add css files (Paht relative to /Content)
        /// </summary>
        protected string[] specificCssCollection = null;
        /// <summary>
        /// Add javascript files (Paht relative to /Scripts) NO JQUERY HERE !
        /// </summary>
        protected string[] specificJSCollection = null;
        /// <summary>
        /// Add links to Javascript generator views
        /// </summary>
        protected string[] dynamicJSCollection = null;
        /// <summary>
        /// Add Javascript JQuery Files here (avoid non JQuery)
        /// </summary>
        protected string[] specificJqueryJSCollection = null;
        /// <summary>
        /// If you need to use css files not stored in the Content folder
        /// </summary>
        protected string[] externalCSS = null;
        /// <summary>
        /// If you need to initialize some javascript variables already available for the $.docReady handler
        /// Use javascript declaration like [var doSomething=true] or [var myMessage='hello it\'s me']
        /// </summary>
        protected string[] jsVariables = null;

        protected Dictionary<enMeta, string> Meta = new Dictionary<enMeta, string>();

        #region  Variables membres
        private T _contentData;
        #endregion
        private List<string> jQueryvalues = new List<string>();
        private List<string> jQuerycssvalues = new List<string>();

        private string lienConfig = "";
        public T ContentData
        {
            get
            {
                return _contentData;
            }
            set
            {
                _contentData = value;
            }
        }

        public string ThemeName
        {
            get
            {
                if (Session["ThemeName"] != null)
                {
                    return Session["ThemeName"].ToString();
                }
                else
                {
                    return ConfigurationManager.AppSettings["DefaultThemeName"].ToString();
                }
            }
        }



        public _Controllers_Base()
        {
            ContentData = Activator.CreateInstance<T>();
        }

        protected override ContentResult Content(string content, string contentType, System.Text.Encoding contentEncoding)
        {
            return base.Content(content.Replace("\t", string.Empty), contentType, contentEncoding);
        }
        /// <summary>
        /// Initilializations the view (Framework Step 2).
        /// </summary>
        /// <param name="contentData">The content data.</param>
        [CacheManager(enCacheMode.NoCache)]
        protected void InitilializationView(string pageTitle, string pageMessage, string[] specificCssCollection, string[] specificJSCollection, string[] dynamicJSCollection, string[] specificJqueryJSCollection, string[] jsVariables, string[] externalCss, bool displayMenus, Dictionary<enMeta, string> metaToAdd)
        {
            INNOVACALL.Framework.Common.Models._Models_Base contentData = ContentData as INNOVACALL.Framework.Common.Models._Models_Base;
            contentData._DisplayMenus = displayMenus;
            contentData._UserLogin = "#Anonyme#";
            contentData._PageTitle = pageTitle;
            contentData._PageMessage = pageMessage;
            contentData._Meta.Add(enMeta.Author, "Laurent Jordi");
            contentData._Meta.Add(enMeta.Copyright, "Innovacall 2012");
            contentData._Meta.Add(enMeta.Generator, "Innovacall Open Source ASP.net MVC 4 Framework");
            contentData._Meta.Add(enMeta.Rating, "General");
            contentData._Meta.Add(enMeta.Rev, "framework/'@'/innovacall.com");
            contentData._Meta.Add(enMeta.Robots, "index, follow");
            foreach (var item in metaToAdd)
            {
                contentData._Meta.Add(item.Key, item.Value);
            }
            if (User != null && User.Identity != null && User.Identity.Name.Length > 0) contentData._UserLogin = User.Identity.Name;
            lienConfig = Server.MapPath(ConfigurationManager.AppSettings["JQueryCss"].ToString());
            jQuerycssvalues = ConfigFile.GetSection(lienConfig, "jquerySectionGroup/jqueryCSSSectionGroup/css");

            for (var i = 0; i < jQuerycssvalues.Count; i++)
            {
                if (jQuerycssvalues[i].Contains("[ThemeName]"))
                {
                    jQuerycssvalues[i] = jQuerycssvalues[i].Replace("[ThemeName]", this.ThemeName);
                }
            }
            contentData._SpecificCSS = jQuerycssvalues;
            if (specificCssCollection != null)
            {
                contentData._SpecificCSS.AddRange(specificCssCollection.ToList());
            }
            if (externalCss != null)
            {
                contentData._ExternalCSS = externalCss.ToList();
            }
            jQueryvalues = ConfigFile.GetSection(lienConfig, "jquerySectionGroup/jqueryJSSectionGroup/j");
            contentData._SpecificJS = jQueryvalues;
            if (specificJSCollection != null)
            {
                contentData._SpecificJS.AddRange(specificJSCollection.ToList());
            }

            if (specificJqueryJSCollection != null)
            {
                contentData._SpecificJqueryJS = specificJqueryJSCollection.ToList();
            }

            if (dynamicJSCollection != null)
            {
                contentData._DynamicJqueryJS = dynamicJSCollection.ToList();
            }

            if (jsVariables != null)
            {
                contentData._JSVariables = jsVariables.ToList();
            }
        }

        public string ReadFileJSStream(string UrlSpecificJqueryJSFile)
        {
            string ligne = null;
            string pathfile = HttpContext.Server.MapPath(UrlSpecificJqueryJSFile);

            var sr = new StreamReader(pathfile);
            ligne = sr.ReadToEnd();
            sr.Close();
            return ligne;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="involvedCodeModel"></param>
        protected void RenderCodeFiles(INNOVACALL.Framework.Common.Models.InvolvedCodeModel involvedCodeModel)
        {
            string FilePath = string.Empty;
            string FileContent = string.Empty;
            try
            {

                foreach (var codeFile in involvedCodeModel)
                {
                    switch (codeFile.Language)
                    {
                        case CodeFormatting.enCodeLanguage._MultipleCodes:
                            RenderCodeFiles(codeFile.SubCodes);
                            break;
                        case CodeFormatting.enCodeLanguage.GeneratedJavascript:
                        case CodeFormatting.enCodeLanguage.GeneratedCss:
                            FilePath = Request.Url.Scheme + "://" + Request.Url.Authority + codeFile.TabStripContent;
                            WebClient client = new WebClient();
                            FileContent = client.DownloadString(FilePath);
                            break;
                        default:
                            if (codeFile.TabStripContent.StartsWith(".."))
                            {
                                FilePath = HttpContext.Server.MapPath("/");
                                FilePath += codeFile.TabStripContent.Replace('/', '\\');
                            }
                            else
                            {
                                FilePath = HttpContext.Server.MapPath(codeFile.TabStripContent);
                            }
                            FileContent = FilePath.ReadContentFile();
                            break;
                    }
                    switch (codeFile.Language)
                    {
                        case CodeFormatting.enCodeLanguage.cSharp:
                            CodeFormatting.CSharpFormat CSharpFormatter = new CodeFormatting.CSharpFormat();
                            CSharpFormatter.Alternate = true;
                            CSharpFormatter.EmbedStyleSheet = false;
                            CSharpFormatter.LineNumbers = true;
                            CSharpFormatter.TabSpaces = 3;
                            codeFile.TabStripContent = CSharpFormatter.FormatCode(FileContent);
                            break;
                        case CodeFormatting.enCodeLanguage.Html:
                            CodeFormatting.HtmlFormat HtmlFormatter = new CodeFormatting.HtmlFormat();
                            HtmlFormatter.Alternate = true;
                            HtmlFormatter.EmbedStyleSheet = false;
                            HtmlFormatter.LineNumbers = true;
                            HtmlFormatter.TabSpaces = 3;
                            codeFile.TabStripContent = HtmlFormatter.FormatCode(FileContent);
                            break;
                        case CodeFormatting.enCodeLanguage.Javascript:
                        case CodeFormatting.enCodeLanguage.GeneratedJavascript:
                            CodeFormatting.JavaScriptFormat JSFormatter = new CodeFormatting.JavaScriptFormat();
                            JSFormatter.EmbedStyleSheet = false;
                            JSFormatter.LineNumbers = true;
                            JSFormatter.Alternate = true;
                            JSFormatter.TabSpaces = 3;
                            codeFile.TabStripContent = JSFormatter.FormatCode(FileContent);
                            break;
                        case CodeFormatting.enCodeLanguage.Css:
                        case CodeFormatting.enCodeLanguage.GeneratedCss:
                            CodeFormatting.CSSFormat CSSFormatter = new CodeFormatting.CSSFormat();
                            CSSFormatter.EmbedStyleSheet = false;
                            CSSFormatter.LineNumbers = true;
                            CSSFormatter.Alternate = true;
                            CSSFormatter.TabSpaces = 3;
                            codeFile.TabStripContent = CSSFormatter.FormatCode(FileContent);
                            break;
                        case CodeFormatting.enCodeLanguage._MultipleCodes:
                            break;
                        default:
                            throw new NotSupportedException();
                    }
                }
            }
            catch (Exception ex)
            {
                FileContent = "#Error reading file#";
            }
        }
    }
}
